home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / basic / _string.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  6.2 KB  |  307 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _string.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/basic.h>
  16.  
  17. #include <stdarg.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20.  
  21.  
  22. //------------------------------------------------------------------------------
  23. // String
  24. //------------------------------------------------------------------------------
  25.  
  26. string_rep::string_rep(const char* p) { s = string::str_dup(p); }
  27.  
  28. string_rep::string_rep(char c)   
  29. { char p[2];
  30.   p[0] = c;
  31.   p[1] = '\0';
  32.   s=string::str_dup(p); 
  33.  }
  34.  
  35. char* string::str_dup(const char* p)
  36. { if (p==nil) error_handler(1,"string::str_dup: nil argument");
  37.   char* q = new char[strlen(p)+1];
  38.   if (q==nil) error_handler(1,"string::str_dup: out of memory");
  39.   strcpy(q,p);
  40.   return q;
  41. }
  42.  
  43. char* string::str_cat(const char* p1, const char* p2)
  44. { char* q = new char[strlen(p1)+strlen(p2)+1];
  45.   if (q==nil) error_handler(1,"string::str_cat: out of memory");
  46.   strcpy(q,p1);
  47.   strcat(q,p2);
  48.   return q;
  49.  }
  50.  
  51. char* string::str_ncat(int argc, char** argv)
  52. { int l=0;
  53.   for(int i=0;i<argc;i++)  l += (strlen(argv[i])+1); 
  54.   char* q = new char[l+1];
  55.   if (q==nil) error_handler(1,"string::str_cat: out of memory");
  56.   q[0] = 0;
  57.   for(i=0;i<argc;i++)
  58.   { strcat(q,argv[i]);
  59.     strcat(q," ");
  60.    }
  61.   return q;
  62.  }
  63.  
  64. void string::read(istream& s, char delim)
  65. { char buf[512];
  66.   char* q = buf+511;
  67.   bool go = true;
  68.  
  69.   operator=(""); // clear string
  70.  
  71.   while (s && go)
  72.   { for(char* p = buf; p < q && s.get(*p); p++)
  73.     { if (*p == delim) 
  74.       { if (delim != '\n') s.putback(*p);
  75.         go = false;
  76.         break;
  77.        }
  78.      } 
  79.     *p = '\0';
  80.     operator+=(buf);
  81.    }
  82.  
  83. }
  84.  
  85.  
  86. #if defined(__GNUG__) || defined(__lucid) || !defined(sparc)
  87.  
  88. string::string(format_string format,...)
  89. { char  buf[512];
  90.   va_list arg_list;
  91.   va_start(arg_list,format);
  92.   vsprintf(buf,format.str,arg_list);
  93.   va_end(arg_list);
  94.   PTR = new string_rep(buf);
  95.  }
  96.  
  97. #else
  98.  
  99. extern "C" void fix_cfront_va_sparc();
  100.  
  101. asm(".seg \"text\"");
  102. asm(".global _fix_cfront_va_sparc");
  103. asm("_fix_cfront_va_sparc:");
  104. asm("retl");
  105. asm("st %i2,[%fp+76]");
  106.  
  107. #define STRING_CONSTRUCTOR(type)\
  108. string::string(const char* format, type, ... )\
  109. { fix_cfront_va_sparc();\
  110.   char buf[512];\
  111.   va_list arg_list;\
  112.   va_start(arg_list,format);\
  113.   vsprintf(buf,format,arg_list);\
  114.   va_end(arg_list);\
  115.   PTR = new string_rep(buf);\
  116.  }
  117.  
  118. STRING_CONSTRUCTOR(int)
  119. STRING_CONSTRUCTOR(long)
  120. STRING_CONSTRUCTOR(float)
  121. STRING_CONSTRUCTOR(double)
  122. STRING_CONSTRUCTOR(char*)
  123. STRING_CONSTRUCTOR(void*)
  124.  
  125. #endif
  126.  
  127.  
  128. int string::length() const  { return strlen(cstring()); }
  129.  
  130. char string::operator[](int i) const
  131. { if (i<0 || length() <= i) 
  132.     error_handler(1,"string[]: index out of range");
  133.   return ptr()->s[i];
  134. }
  135.  
  136. char& string::operator[](int i)
  137. { if (i<0 || length() <= i) 
  138.     error_handler(1,"string[]: index out of range");
  139.   *this = cstring();    //disconnect
  140.   return ptr()->s[i];
  141. }
  142.  
  143. string  string::operator+(const char* x)  const
  144. { char *p = str_cat(cstring(),x);
  145.   string res = p;
  146.   delete p;
  147.   return res;
  148. }
  149.  
  150. string  string::operator+(const string& x)  const
  151. { char *p = str_cat(cstring(),x.cstring());
  152.   string res = p;
  153.   delete p;
  154.   return res;
  155. }
  156.  
  157. string& string::operator+=(const string& x) 
  158. { *this = *this + x; 
  159.   return *this; 
  160.  }
  161.  
  162. //friends
  163.  
  164. int operator==(const string& x, const string& y) 
  165. { return strcmp(x.cstring(),y.cstring())==0; }
  166.  
  167. int operator==(const string& x, const char* y) 
  168. { return strcmp(x.cstring(),y)==0; }
  169.  
  170. int operator!=(const string& x, const string& y) 
  171. { return strcmp(x.cstring(),y.cstring())!=0; }
  172.  
  173. int operator!=(const string& x, const char* y) 
  174. { return strcmp(x.cstring(),y)!=0; }
  175.  
  176. int operator<(const string& x, const string& y)  
  177. { return strcmp(x.cstring(),y.cstring())<0; }
  178.  
  179. int operator>(const string& x, const string& y)  
  180. { return strcmp(x.cstring(),y.cstring())>0; }
  181.  
  182. int operator<=(const string& x, const string& y) 
  183. { return strcmp(x.cstring(),y.cstring())<=0; }
  184.  
  185. int operator>=(const string& x, const string& y) 
  186. { return strcmp(x.cstring(),y.cstring())>=0; }
  187.  
  188.  
  189.  
  190. istream& operator>>(istream& in, string& x)
  191. { char buf[256];
  192.   char* p = buf;
  193.  
  194.   //skip leading white space (but not eol if in = cin)
  195.   while (in.get(*p) && isspace(*p) && (&in != &cin || *p != '\n')); 
  196.  
  197.   if (in && *p != '\n')
  198.   { p++;
  199.     while (in.get(*p) && !isspace(*p)) p++;
  200.    }
  201.  
  202.   *p = '\0';
  203.   x.operator=(buf);
  204.   return in;
  205. }
  206.  
  207.  
  208. ostream& operator<<(ostream& out, const string& x) 
  209. { return out << x.cstring(); }
  210.  
  211.  
  212. string string::sub(int i, int j) const
  213. {
  214.   if (j >= length()) j = length() - 1;
  215.  
  216.   if (i < 0) i = 0;
  217.  
  218.   int l = j-i+1;
  219.  
  220.   if (l <= 0)  return string("");
  221.  
  222.   char* q = new char[l+1];
  223.   strncpy(q,cstring()+i,l);
  224.   q[l] = '\0';
  225.  
  226.   string s(q);
  227.   delete q;
  228.   return s;
  229. }
  230.  
  231. int string::pos(string s1, int i) const
  232. {
  233.   int l1 = s1.length();
  234.   if (l1==0 || i >= length()) return -1;
  235.  
  236.   char c = s1[0];
  237.  
  238.   char* q = cstring() + i;
  239.   while (*q)
  240.     { while ( (*q) && (*q != c) ) q++;
  241.       if ( strncmp(q,s1.cstring(),l1)==0 ) break ;
  242.       if (*q) q++;
  243.      }
  244.   return (*q) ? (q - cstring())/ sizeof(char) :  -1;
  245. }
  246.  
  247. string string::insert(string s, int i) const
  248. { return sub(0,i-1) + s + sub(i,length()-1); }
  249.  
  250. string string::insert(int i, string s) const
  251. { return sub(0,i-1) + s + sub(i,length()-1); }
  252.  
  253.  
  254. string string::del(int i, int j) const
  255. { return sub(0,i-1) + sub(j+1,length()-1); }
  256.  
  257. string string::del(const string& s, int n) const
  258. { return replace(s,"",n); }
  259.  
  260.  
  261.  
  262. string string::replace(int i, int j, const string& s) const
  263. { return sub(0,i-1) + s + sub(j+1,length()-1); }
  264.  
  265. string string::replace(const string& s1, const string& s2, int n) const 
  266.   // replace n-th (all if n=0) occurrence of s1 by s2 
  267.  
  268.   int i = 0;
  269.   int match = 0;  
  270.  
  271.   int l1 = s1.length();
  272.  
  273.   string tmp;
  274.  
  275.   for(;;)
  276.   { int j = pos(s1,i);
  277.     if (j < 0 ) break;
  278.     tmp += sub(i,j-1);
  279.  
  280.     if (n==0 || ++match == n)
  281.        tmp += s2;
  282.     else
  283.        tmp += s1;
  284.  
  285.     i = j+l1;
  286.    }
  287.  
  288.   tmp += sub(i,length()-1);
  289.  
  290.   return tmp;
  291.  
  292.  }
  293.  
  294.  
  295. string string::format(string f) const
  296.   char buf[512];
  297.   sprintf(buf,~f,cstring());
  298.   return buf;
  299.  
  300.  }
  301.  
  302.  
  303. int compare(const string& x, const string& y) { return strcmp(x,y); }
  304.